package com.winsdom.service.customer.impl;

import com.winsdom.entity.customer.CustomerEnterpriseCreateRequest;
import com.winsdom.mapper.customer.CustomerEnterpriseCreateMapper;
import com.winsdom.service.customer.CustomerEnterpriseCreateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 企业客户创建服务实现类，负责处理企业客户创建的完整业务流程。
 * 该类通过调用Mapper接口完成数据库操作，并通过事务管理确保数据一致性。
 * 包含客户主表、企业扩展表、地址信息、联系人信息、营业执照及配置信息的插入逻辑。
 */
@Service
public class CustomerEnterpriseCreateServiceImpl implements CustomerEnterpriseCreateService {

    @Autowired
    private CustomerEnterpriseCreateMapper enterpriseCreateMapper;

    /**
     * 创建企业客户的完整业务流程（包含多表关联插入）
     * <p>
     * 流程说明：
     * 1. 校验并设置默认业务参数
     * 2. 插入客户主表记录并获取自增ID
     * 3. 插入企业客户扩展信息
     * 4. 批量插入地址信息（支持多地址）
     * 5. 插入联系人信息及联系人-楼盘分类关联关系
     * 6. 插入营业执照图片信息
     * 7. 插入通知配置和账单配置信息
     * <p>
     * 该方法使用@Transactional注解确保所有数据库操作在同一个事务中执行，
     * 若中途发生异常将自动回滚，保证数据一致性。
     *
     * @param createInfo 企业客户创建信息实体，包含完整的客户创建数据
     * @return 新创建客户的ID
     * @throws IllegalArgumentException 当updateUserId为空时抛出
     */
    @Override
    @Transactional(rollbackFor = Exception.class) // 声明事务，异常时自动回滚
    public Long createEnterprise(CustomerEnterpriseCreateRequest createInfo) {
        // ====================== 1. 参数校验与默认值设置 ======================
        // 设置默认业务状态（0-未处理，1-已创建）
        createInfo.setLegalProcedure(0);
        createInfo.setStatus(1);
        // 校验必填参数：更新用户ID不能为空（用于审计追踪）
        if (createInfo.getUpdateUserId() == null) {
            throw new IllegalArgumentException("updateUserId不能为空，需指定操作人ID");
        }

        // ====================== 2. 插入客户主表 ======================
        // 插入客户主表记录（存储基础客户信息）
        enterpriseCreateMapper.insertCustomer(createInfo);
        // 获取数据库生成的自增客户ID（用于后续关联表插入）
        Long customerId = enterpriseCreateMapper.getLastInsertId();
        createInfo.setCustomerId(customerId); // 将客户ID回填到实体中

        // ====================== 3. 插入企业客户扩展表 ======================
        // 插入企业特有信息（如企业类型、注册资本等）
        enterpriseCreateMapper.insertCustomerEnterprise(createInfo);

        // ====================== 4. 插入地址信息（支持多地址） ======================
        if (createInfo.getAddresses() != null && !createInfo.getAddresses().isEmpty()) {
            // 为每个地址设置客户ID关联
            createInfo.getAddresses().forEach(address -> address.setCustomerId(customerId));
            // 批量插入地址信息到地址表
            enterpriseCreateMapper.insertCustomerAddress(createInfo.getAddresses());
        }

        // ====================== 5. 插入联系人及关联楼盘分类 ======================
        if (createInfo.getContactInfos() != null && !createInfo.getContactInfos().isEmpty()) {
            for (CustomerEnterpriseCreateRequest.ContactInfo contact : createInfo.getContactInfos()) {
                // 设置联系人所属客户ID
                contact.setCustomerId(customerId);
                // 插入联系人基本信息到联系人表
                enterpriseCreateMapper.insertContactPerson(contact);
                // 获取新插入的联系人ID
                Long contactId = enterpriseCreateMapper.getLastContactPersonId();

                // 处理联系人关联的楼盘分类（若有）
                if (contact.getReceiveProperties() != null && !contact.getReceiveProperties().isEmpty()) {
                    // 根据属性名称查询对应的分类ID列表
                    List<Long> categoryIds = enterpriseCreateMapper.getPropertyCategoryIdsByNames(contact.getReceiveProperties());
                    if (!categoryIds.isEmpty()) {
                        // 插入联系人与分类的关联关系到中间表
                        enterpriseCreateMapper.insertContactPersonProperty(contactId, categoryIds);
                    }
                }
            }
        }

        // ====================== 6. 插入营业执照图片 ======================
        if (createInfo.getBusinessLicenseImage() != null) {
            // 插入营业执照文件路径到证书表
            enterpriseCreateMapper.insertCustomerCertificate(customerId, createInfo.getBusinessLicenseImage());
        }

        // ====================== 7. 插入系统配置信息 ======================
        // 插入通知配置（如消息接收方式）
        enterpriseCreateMapper.insertNotificationConfig(createInfo);
        // 插入账单配置（如发票开具信息）
        enterpriseCreateMapper.insertBillingConfig(createInfo);

        return customerId; // 返回新创建的客户ID
    }
}